<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // vue3响应式原理
        // Vue3响应式原理通过的是 Proxy对象 实现的

        // Proxy 对象用于创建一个对象的代理，从而实现基本操作的拦截和自定义（如属性查找、赋值、枚举、函数调用等）。
        // 注意: reactive 和 ref 都可以实现数据的响应式,这里reactive的底层实现就是使用的 proxy
        // 注意: ref 包裹一个对象(引用数据类型),此时这个对象是交给reactive处理了,生成一个代理对象放到 ref 对象的.value属性上
        const obj1 = {
            name: '张三',
            age: 18,
            height: 180,
            weight: 150
        }
        console.log('obj1->', obj1);
        // 功能: 创建一个代理对象
        // 参数有两个:
        //    参数一: 元对象
        //    参数二: 配置对象,配置操作代理对象的拦截函数,总共有13个配置项
        // 返回值: 返回一个代理对象
        const obj2 = new Proxy(obj1, {
            // 只要是获取代理对象下的属性,都会走get
            // target -> 元对象
            // prop -> 属性,当前取得属性名
            get(target, prop) {
                // return target[prop]
                // Reflect.get(target, prop) 作用和 target[prop] 一摸一样,去target取出prop属性
                return Reflect.get(target, prop)
                // Reflect 叫做反射
                // 是一个内置对象,不能被new(和Math一样不能被new)
                // Reflect它和【proxy handler】一样,有13中方法,和proxy一一对应
                // (个人理解:Reflect就是为了Proxy)
            },
            // target -> 元对象
            // prop -> 属性
            // val -> 设置得值
            set(target, prop, val) {
                // target[prop] = val;
                // 数据改变之后,这里进行页面更新
                return Reflect.set(target, prop, val)
            },
            deleteProperty(target, prop) {
                // delete target[prop]
                // return true
                return Reflect.deleteProperty(target, prop)
            },
            has(target, prop) {
                // return prop in target
                return Reflect.has(target, prop)
            }
        })
        console.log('obj2->', obj2);
        console.log(obj2.name);
        console.log(obj2.age);
        obj2.name = '赵四'
        delete obj2.age
        console.log(obj2);

    </script>
</body>

</html>